package com.xbongbong.paas.service.impl;

import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.model.DeveloperModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskCountDTO;
import com.xbongbong.paas.pojo.vo.FeeCompanyVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskCountVO;
import com.xbongbong.paas.pojo.workflow.task.dto.WorkflowNodeTaskCountDTO;
import com.xbongbong.paas.pojo.workflow.task.vo.WorkflowNodeTaskCountVO;
import com.xbongbong.paas.service.AppHomeService;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.PaasProcessNodeTaskService;
import com.xbongbong.paas.service.PackageService;
import com.xbongbong.paas.service.UserConfigService;
import com.xbongbong.paas.service.workflow.WorkflowApproveListPageOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.HomeBottomMenuEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.home.pojo.HomeBottomPojo;
import com.xbongbong.pro.home.pojo.dto.HomeBottomDTO;
import com.xbongbong.pro.home.pojo.vo.HomeBottomVO;
import com.xbongbong.pro.message.pojo.dto.MessageCountDTO;
import com.xbongbong.pro.message.pojo.vo.MessageCountVO;
import com.xbongbong.pro.message.service.PushLinkService;
import com.xbongbong.pro.packageInfo.pojo.vo.BasePackageInfoVO;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author: wufeng
 * @date: 2018/8/31 9:46
 * @desrcption: APP首页-卡片（我审批的，我发起的，报表，消息，常用表单）
 */
@Service("appHomeService")
public class AppHomeServiceImpl implements AppHomeService {

    private static final Logger LOG = LoggerFactory.getLogger(AppHomeServiceImpl.class);

    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PushLinkService pushLinkService;
    @Resource
    private PaasProcessNodeTaskService paasProcessNodeTaskService;
    @Resource
    private UserModel userModel;
    @Resource
    private PackageService packageService;
    @Resource
    private DeveloperModel developerModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private WorkflowApproveListPageOperationService workflowApproveListPageOperationService;
    @Resource
    private UserConfigService userConfigService;

    @Override
    public HomeBottomVO bottomList(HomeBottomDTO homeBottomDTO) throws XbbException {
        HomeBottomVO homeBottomVO = new HomeBottomVO();
        UserVO userVO = homeBottomDTO.getLoginUser();
        List<HomeBottomPojo> bottomList = new ArrayList<>();
        try {
            Integer unRead = null;
            MessageCountDTO messageCountDTO = new MessageCountDTO(1, 100, homeBottomDTO.getCorpid(), homeBottomDTO.getUserId());
            MessageCountVO messageCountVO = pushLinkService.countUnread(messageCountDTO);
            if (Objects.nonNull(messageCountVO)) {
                unRead = messageCountVO.getCount();
            }
            Boolean hasProcessPermission = homeBottomDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.PROCESS.getAlias());
            Integer processUnDeal = null;
            if (hasProcessPermission) {
                if (commonHelp.isOpenWorkFlow(homeBottomDTO.getCorpid())) {
                    // 新工作流
                    WorkflowNodeTaskCountDTO workflowNodeTaskCountDTO = new WorkflowNodeTaskCountDTO();
                    workflowNodeTaskCountDTO.setCorpid(homeBottomDTO.getCorpid());
                    workflowNodeTaskCountDTO.setUserId(homeBottomDTO.getUserId());
                    WorkflowNodeTaskCountVO workflowNodeTaskCountVO = workflowApproveListPageOperationService.count(workflowNodeTaskCountDTO);
                    if (Objects.nonNull(workflowNodeTaskCountVO)) {
                        processUnDeal = workflowNodeTaskCountVO.getCc() + workflowNodeTaskCountVO.getCreate() + workflowNodeTaskCountVO.getTodo();
                    }
                } else {
                    // 老审批
                    ProcessNodeTaskCountDTO processNodeTaskCountDTO = new ProcessNodeTaskCountDTO();
                    BeanUtil.copyProperties(homeBottomDTO, processNodeTaskCountDTO);
                    ProcessNodeTaskCountVO processNodeTaskCountVO =paasProcessNodeTaskService.count(processNodeTaskCountDTO);
                    if (Objects.nonNull(processNodeTaskCountVO)) {
                        processUnDeal = processNodeTaskCountVO.getCc() + processNodeTaskCountVO.getCreate() + processNodeTaskCountVO.getTodo();
                    }
                }
            }

            // 访客计划模块
            PaasMenuEntity paasMenuEntity = paasMenuModel.getByAlias(XbbRefTypeEnum.COMMUNICATE_PLAN.getAlias(), null, homeBottomDTO.getCorpid());
            // CRM模块开启
            boolean appEnable =  paasAppService.validateAppEnable(null, XbbRefTypeEnum.CRM.getAlias(), SaasMarkEnum.SAAS.getCode(), homeBottomDTO.getCorpid());
            // 判断是否是专注模式
            boolean isFocus = userConfigService.isFocus(homeBottomDTO);
            for(HomeBottomMenuEnum bottomMenuEnum: HomeBottomMenuEnum.values()) {
                HomeBottomPojo homeBottomPojo = new HomeBottomPojo();
                homeBottomPojo.setName(bottomMenuEnum.getName());
                AccessLinkEnum accessLinkEnum = bottomMenuEnum.getAccessLinkEnum();
                homeBottomPojo.setIconfont(accessLinkEnum.getIcon());
                homeBottomPojo.setUrl(accessLinkEnum.getMobileUrl());
                homeBottomPojo.setShow(PaasConstant.SHOW);
                if (isFocus){
                    if (bottomMenuEnum == HomeBottomMenuEnum.HOME || bottomMenuEnum == HomeBottomMenuEnum.TASK){
                        homeBottomPojo.setShow(PaasConstant.NONE_SHOW);
                    }
                }else {
                    if (bottomMenuEnum == HomeBottomMenuEnum.FOCUS_HOME || bottomMenuEnum == HomeBottomMenuEnum.BI){
                        homeBottomPojo.setShow(PaasConstant.NONE_SHOW);
                    }
                }
                if (Objects.equals(bottomMenuEnum.getType(), HomeBottomMenuEnum.MESSAGE.getType()) && Objects.nonNull(unRead)) {
                    if (unRead <= 99) {
                        homeBottomPojo.setCount(unRead);
                    } else {
                        homeBottomPojo.setCount("...");
                    }
                } else if (Objects.equals(bottomMenuEnum.getType(), HomeBottomMenuEnum.PROCESS.getType()) && hasProcessPermission && Objects.nonNull(processUnDeal)  ) {
                    // 流程权限存在，才能有此记录
                    if (processUnDeal <= 99) {
                        homeBottomPojo.setCount(processUnDeal);
                    } else {
                        homeBottomPojo.setCount("...");
                    }
                }
                // 是否访客计划底部菜单
                boolean isCommunicatePlan = Objects.equals(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), bottomMenuEnum.getBusinessType());
                if (isCommunicatePlan) {
                    // 判断是否该增加底部访客计划菜单
                    boolean enable = (Objects.nonNull(paasMenuEntity) && Objects.equals(paasMenuEntity.getEnable(), 1) && appEnable);
                    boolean hasPermission =  userVO.isAdminOrBoss() || userVO.getPermSet().contains(XbbRefTypeEnum.COMMUNICATE_PLAN.getAlias());
                    if (enable && hasPermission) {
                        PaasFormEntity paasFormEntity = paasFormModel.getByMenuIdAndBusinessType(paasMenuEntity.getId().intValue(), homeBottomDTO.getCorpid(), XbbRefTypeEnum.COMMUNICATE_PLAN.getCode());
                        if(Objects.isNull(paasFormEntity)) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                        }
                        String url = AccessLinkEnum.ADMIN_COMMUNICATE_PLAN.getMobileUrl();
                        Boolean isAdminCommunicatePlan = true;
                        UserEntity userEntity = new UserEntity();
                        BeanUtil.copyProperties(userVO, userEntity);
                        Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
                        if (dataPermission != null && Objects.equals(dataPermission, DataPermissionEnum.SELF.getCode())) {
                            // 18609，数据权限仅本人时只展示自己的数据（我的），如果不是的话则一进入访客计划列表时展示统计界面
                            url = AccessLinkEnum.COMMUNICATE_PLAN.getMobileUrl();
                            isAdminCommunicatePlan = false;
                        }
                        homeBottomPojo.setIsAdminCommunicatePlan(isAdminCommunicatePlan);
                        StringBuilder stringBuilder = new StringBuilder(url)
                                .append("?subBusinessType=").append(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode())
                                .append("&businessType=").append(XbbRefTypeEnum.COMMUNICATE_PLAN.getCode())
                                .append("&appId=").append(paasMenuEntity.getAppId())
                                .append("&menuId=").append(paasMenuEntity.getId())
                                .append("&formId=").append(paasFormEntity.getId())
                                .append("&idAdminOrBoss=").append(userVO.isAdminOrBoss())
                                .append("&saasMark=").append(paasMenuEntity.getSaasMark());
                        homeBottomPojo.setUrl(stringBuilder.toString());
                    } else {
                        continue;
                    }
                }
                bottomList.add(homeBottomPojo);
            }
            homeBottomVO.setBottomList(bottomList);
            BasePackageInfoVO basePackageInfoVO = packageService.getBasePackageInfoFromRedis(homeBottomDTO.getCorpid());
            FeeCompanyVO feeCompanyVO = new FeeCompanyVO();
            Integer feeType = basePackageInfoVO.getFeeType();
            feeCompanyVO.setCorpid(homeBottomDTO.getCorpid());
            feeCompanyVO.setFeeName(basePackageInfoVO.getFeeName());
            feeCompanyVO.setFeeTypeName(PackageTypeEnum.getNameByType(basePackageInfoVO.getFeeType()));
            feeCompanyVO.setStartTime(basePackageInfoVO.getFeeStartTime());
            feeCompanyVO.setEndTime(basePackageInfoVO.getFeeEndTime());
            feeCompanyVO.setFeeType(feeType);
            feeCompanyVO.setIndustry(basePackageInfoVO.getIndustry());
            feeCompanyVO.setScale(basePackageInfoVO.getScale());
            Integer isProfessionalEdition = Objects.equals(feeType, PackageTypeEnum.STANDARD.getType()) ?
                    PackageTypeEnum.STANDARD.getType() : PackageTypeEnum.ADVANCED.getType();
            feeCompanyVO.setIsProfessionalEdition(isProfessionalEdition);
            // 开发者
            boolean developer = false;
            if (basePackageInfoVO != null && Objects.equals(PackageTypeEnum.ULTIMATE.getType(), basePackageInfoVO.getFeeType())) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, homeBottomDTO.getCorpid());
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("developer", homeBottomDTO.getUserId());
                Integer count = developerModel.getEntitysCount(param);
                developer = count >= 1;
            }
            homeBottomVO.setDeveloper(developer);
            homeBottomVO.setFeeCompanyVO(feeCompanyVO);

            boolean isOpenWorkflow = commonHelp.isOpenWorkFlow(homeBottomDTO.getCorpid());
            boolean isCustomerPublicPoolSeniorModel = commonHelp.isCustomerPublicPoolSeniorModel(homeBottomDTO.getCorpid());
            boolean isCluePublicPoolSeniorModel = commonHelp.isCluePublicPoolSeniorModel(homeBottomDTO.getCorpid());
            homeBottomVO.setIsOpenWorkflow(isOpenWorkflow);
            homeBottomVO.setIsCustomerPublicPoolSeniorModel(isCustomerPublicPoolSeniorModel);
            homeBottomVO.setIsCluePublicPoolSeniorModel(isCluePublicPoolSeniorModel);

            String officPreviewUrl = userConfigService.getOfficPreviewUrl(homeBottomDTO.getCorpid(), homeBottomDTO.getUserId());
            homeBottomVO.setOfficePreviewUrl(officPreviewUrl);

        } catch (Exception e) {
            LOG.error("appHome.bottomList 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return homeBottomVO;
    }
}
